package org.dromara.common.encrypt.core.encryptor;

import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.encrypt.core.EncryptContext;
import org.dromara.common.encrypt.enumd.AlgorithmType;
import org.dromara.common.encrypt.enumd.EncodeType;
import org.dromara.common.encrypt.utils.EncryptUtils;



/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：RSA算法实现
 */
public class RsaEncryptor extends AbstractEncryptor {

    /**
     * 加密上下文 用于encryptor传递必要的参数。
     */
    private final EncryptContext context;

    /**
     * 构造函数，初始化RSA加密器
     *
     * @param context 加密上下文，包含公钥和私钥信息
     * @throws IllegalArgumentException 如果公钥或私钥为空，则抛出此异常
     */
    public RsaEncryptor(EncryptContext context) {
        super(context);
        // 从加密上下文中获取公钥和私钥
        String privateKey = context.getPrivateKey();
        String publicKey = context.getPublicKey();
        // 验证公钥和私钥是否为空，如果任一为空则抛出异常
        if (StringUtils.isAnyEmpty(privateKey, publicKey)) {
            throw new IllegalArgumentException("RSA公私钥均需要提供，公钥加密，私钥解密。");
        }
        // 将加密上下文保存在实例变量中，以供后续使用
        this.context = context;
    }

    /**
     * 获得当前算法
     * 返回当前实现类所使用的算法类型
     *
     * @return AlgorithmType 当前实现类使用的算法类型为RSA
     */
    @Override
    public AlgorithmType algorithm() {
        return AlgorithmType.RSA;
    }

    /**
     * 根据指定的编码类型对值进行加密
     * 此方法主要处理RSA加密，支持HEX和BASE64两种编码类型
     *
     * @param value 待加密的字符串值
     * @param encodeType 加密后的编码类型，用于指定加密方式
     * @return 加密后的字符串
     */
    @Override
    public String encrypt(String value, EncodeType encodeType) {
        // 当编码类型为HEX时，使用HEX编码方式进行加密
        if (encodeType == EncodeType.HEX) {
            return EncryptUtils.encryptByRsaHex(value, context.getPublicKey());
        } else {
            // 默认情况下使用BASE64编码方式进行加密
            return EncryptUtils.encryptByRsa(value, context.getPublicKey());
        }
    }

    /**
     * 解密
     * 使用RSA私钥对字符串进行解密
     *
     * @param value 待解密的字符串
     * @return 解密后的字符串
     */
    @Override
    public String decrypt(String value) {
        // 使用EncryptUtils工具类的decryptByRsa方法进行解密，该方法接受待解密字符串和私钥作为参数
        return EncryptUtils.decryptByRsa(value, context.getPrivateKey());
    }
}
